package com.pinla.util;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Richard
 * @version 1.0
 */
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.*;


public class StringUtils {
	private static String defStringValue = "";
	public StringUtils() {
	}

	public static void main(String[] args) {
		StringUtils stringUtils1 = new StringUtils();
	}

	/**
	 * Used by the hash method.
	 */
	private static MessageDigest digest = null;

	/**
	 * Hashes a String using the Md5 algorithm and returns the result as a
	 * String of hexadecimal numbers. This method is synchronized to avoid
	 * excessive MessageDigest object creation. If calling this method becomes
	 * a bottleneck in your code, you may wish to maintain a pool of
	 * MessageDigest objects instead of using this method.
	 * <p>
	 * A hash is a one-way function -- that is, given an
	 * input, an output is easily computed. However, given the output, the
	 * input is almost impossible to compute. This is useful for passwords
	 * since we can store the hash and a hacker will then have a very hard time
	 * determining the original password.
	 * <p>
	 * take their plain text password, compute the hash, and compare the
	 * generated hash to the stored hash. Since it is almost impossible that
	 * two passwords will generate the same hash, we know if the user gave us
	 * the correct password or not. The only negative to this system is that
	 * password recovery is basically impossible. Therefore, a reset password
	 * method is used instead.
	 *
	 * @param data the String to compute the hash of.
	 * @return a hashed version of the passed-in String
	 */
	public synchronized static final String hash(String data) {
		if (digest == null) {
			try {
				digest = MessageDigest.getInstance("MD5");
			}
			catch (NoSuchAlgorithmException nsae) {
				System.err.println("Failed to load the MD5 MessageDigest. " +
					"system will be unable to function normally.");
				nsae.printStackTrace();
			}
		}
		//Now, compute hash.
		digest.update(data.getBytes());
		return toHex(digest.digest());
	}

	public static final String toHex(byte hash[]) {
		StringBuffer buf = new StringBuffer(hash.length * 2);
		int i;

		for (i = 0; i < hash.length; i++) {
			if ( ( (int) hash[i] & 0xff) < 0x10) {
				buf.append("0");
			}
			buf.append(Long.toString( (int) hash[i] & 0xff, 16));
		}
		return buf.toString();
	}

	public static final String encodeHex(byte[] bytes) {
		StringBuffer buf = new StringBuffer(bytes.length * 2);
		int i;

		for (i = 0; i < bytes.length; i++) {
			if ( ( (int) bytes[i] & 0xff) < 0x10) {
				buf.append("0");
			}
			buf.append(Long.toString( (int) bytes[i] & 0xff, 16));
		}
		return buf.toString();
	}

	public static final String replace(String line, String oldString,
									   String newString) {
		if (line == null) {
			return null;
		}
		int i = 0;
		if ( (i = line.indexOf(oldString, i)) >= 0) {
			char[] line2 = line.toCharArray();
			char[] newString2 = newString.toCharArray();
			int oLength = oldString.length();
			StringBuffer buf = new StringBuffer(line2.length);
			buf.append(line2, 0, i).append(newString2);
			i += oLength;
			int j = i;
			while ( (i = line.indexOf(oldString, i)) > 0) {
				buf.append(line2, j, i - j).append(newString2);
				i += oLength;
				j = i;
			}
			buf.append(line2, j, line2.length - j);
			return buf.toString();
		}
		return line;
	}

	/**
	 * Replaces all instances of oldString with newString in line with the
	 * added feature that matches of newString in oldString ignore case.
	 *
	 * @param line the String to search to perform replacements on
	 * @param oldString the String that should be replaced by newString
	 * @param newString the String that will replace all instances of oldString
	 *
	 * @return a String will all instances of oldString replaced by newString
	 */
	public static final String replaceIgnoreCase(String line, String oldString,
												 String newString) {
		if (line == null) {
			return null;
		}
		String lcLine = line.toLowerCase();
		String lcOldString = oldString.toLowerCase();
		int i = 0;
		if ( (i = lcLine.indexOf(lcOldString, i)) >= 0) {
			char[] line2 = line.toCharArray();
			char[] newString2 = newString.toCharArray();
			int oLength = oldString.length();
			StringBuffer buf = new StringBuffer(line2.length);
			buf.append(line2, 0, i).append(newString2);
			i += oLength;
			int j = i;
			while ( (i = lcLine.indexOf(lcOldString, i)) > 0) {
				buf.append(line2, j, i - j).append(newString2);
				i += oLength;
				j = i;
			}
			buf.append(line2, j, line2.length - j);
			return buf.toString();
		}
		return line;
	}

	/**
	 * Replaces all instances of oldString with newString in line.
	 * The count Integer is updated with number of replaces.
	 *
	 * @param line the String to search to perform replacements on
	 * @param oldString the String that should be replaced by newString
	 * @param newString the String that will replace all instances of oldString
	 *
	 * @return a String will all instances of oldString replaced by newString
	 */
	public static final String replace(String line, String oldString,
									   String newString, int[] count) {
		if (line == null) {
			return null;
		}
		int i = 0;
		if ( (i = line.indexOf(oldString, i)) >= 0) {
			int counter = 0;
			counter++;
			char[] line2 = line.toCharArray();
			char[] newString2 = newString.toCharArray();
			int oLength = oldString.length();
			StringBuffer buf = new StringBuffer(line2.length);
			buf.append(line2, 0, i).append(newString2);
			i += oLength;
			int j = i;
			while ( (i = line.indexOf(oldString, i)) > 0) {
				counter++;
				buf.append(line2, j, i - j).append(newString2);
				i += oLength;
				j = i;
			}
			buf.append(line2, j, line2.length - j);
			count[0] = counter;
			return buf.toString();
		}
		return line;
	}

	/**
	 * This method takes a string which may contain HTML tags (ie, &lt;b&gt;,
	 * &lt;table&gt;, etc) and converts the '&lt'' and '&gt;' characters to
	 * their HTML escape sequences.
	 *
	 * @param input the text to be converted.
	 * @return the input string with the characters '&lt;' and '&gt;' replaced
	 *  with their HTML escape sequences.
	 */
	public static final String escapeHTMLTags(String input) {
		//Check if the string is null or zero length -- if so, return
		//what was sent in.
		if (input == null || input.length() == 0) {
			return input;
		}
		//Use a StringBuffer in lieu of String concatenation -- it is
		//much more efficient this way.
		StringBuffer buf = new StringBuffer(input.length());
		char ch = ' ';
		for (int i = 0; i < input.length(); i++) {
			ch = input.charAt(i);
			if (ch == '<') {
				buf.append("&lt;");
			}
			else if (ch == '>') {
				buf.append("&gt;");
			}
			else {
				buf.append(ch);
			}
		}
		return buf.toString();
	}

	/**
	 * 处理string类型null
	 *
	 * @param strin 传入的字符串
	 * @param isUseDef 是否使用默认值
	 *
	 * @return String 如果为空的话，根据isUseDef true返回默认值，false返回""
	 */

	public static String dealNull(String strIn, boolean isUseDef) {
		String ret = "";

		if (strIn == null) {
			if (isUseDef) {
				ret = defStringValue;
			}
			else {
				ret = " ";
			}
		}
		else {
			ret = strIn;
		}

		return ret;
	}

	public static Object dealNull(Object obj) {
		Object returnstr = null;
		if (obj == null) {
			returnstr = (Object) ("");

		}
		else {
			returnstr = obj;

		}
		return returnstr;

	}

	/**
	 * 处理boolean类型
	 *
	 * @param boolean thebool
	 *
	 * @return String 根据true返回"是"，false返回"否"
	 */

	public static String dealBoolean(boolean thebool) {

		if (thebool) {
			return "是";
		}
		else {
			return "否";
		}
	}

	/**
	 * 处理boolean类型(通过数据库中的bit类型)
	 *
	 * @param int theint 传入的0，1
	 *
	 * @return String 根据1返回"是"，0返回"否"
	 */

	public static String dealBooleanByInt(int theint) {

		if (theint == 1) {
			return "是";
		}
		else {
			return "否";
		}
	}

	/**
	 * 从srcString中截取定长的字符串。
	 * 1、srcString为null,则返回""。
	 * 2、fixLength<1，则返回""。
	 * 3、fixLength >= srcString.length() ，则返回srcString。
		 * 4、fixLength < srcString.length()，返回srcString最前面的部分字符串subString + suffixString
	 * 返回的字符串的长度为fixLength。
	 * 如果suffixString为null则返回srcString最前面fixLength个字符串。
	 * @param srcString
	 * @param fixLength
	 * @param suffixString
	 * @return
	 */
	public static String getFixLengthString(String srcString, int fixLength,
											String suffixString) {
		String fixString = "";
		//srcString为null或者fixLength小于1，则返回""
		if (srcString != null && fixLength > 0) {
			//要截取得字符串长度大于srcString的长度，则返回srcString。
			if (fixLength >= srcString.length()) {
				fixString = srcString;
			}
			else {

				if (suffixString == null) {
					//如果suffixString为null，则返回srcString的前fixLength个字符
					fixString = srcString.substring(0, fixLength);
				}
				else if (suffixString.length() >= fixLength) {
					//如果suffixString.length() >= fixLength，则返回suffixString的前fixLength个字符
					fixString = suffixString.substring(0, fixLength);
				}
				else {
					//返回srcString的部分＋suffixString
					fixString = srcString.substring(0,
						fixLength - suffixString.length()) + suffixString;
				}
			}
		}
		return fixString;
	}

	/**
	 * 从srcString中截取定长的字符串并转换为long型，同时加上增量。
	 * 1、srcString为null或"",则返回srcString。
	 * 2、start<0，则返回srcString。
	 * 3、end<0 ,则返回srcString。
	 * 4、increase<0 ,则返回srcString。
	 * 5、end-start<=0 ,则返回srcString。
	 * 返回的字符串的长度为srcString.length()。
	 * @param srcString 源字符串
	 * @param start 截取起点
	 * @param end 截取终点
	 * @param increase 增量
	 * @return
	 */
	public static String addNumber(String srcString, int start, int end,
								   int increase) {
		String tempStr = "";
		int preLength = 0;
		int aftLength = 0;

		if ( (srcString == null) || (srcString == "")) {
			return srcString;
		}
		if ( (start < 0) || (end < 0) || (increase < 0) || (end - start) <= 0 ||
			(start > srcString.length()) || (end > srcString.length())) {
			return srcString;
		}
		//截取指定长度的字符串
		tempStr = srcString.substring(start, end);
		preLength = tempStr.length();
		//字符串转换为long型后加上增量，然后变回字符串
		tempStr = "" + (Long.parseLong(tempStr) + increase);
		aftLength = tempStr.length();
		//加上增量后，字符串长度变小，在串首加入preLength-aftLength个0
		if (preLength > aftLength) {
			tempStr = addZeroPrefix(tempStr, preLength, aftLength);
			//加上增量后，字符串长度变大，截取末尾的end-start个字符
		}
		if (preLength < aftLength) {
			tempStr = tempStr.substring(aftLength - preLength);
			//拼接字符串
		}
		srcString = srcString.substring(0, start) + tempStr +
			srcString.substring(end);
		//返回srcString
		return srcString;
	}

	/**
	 * 从srcString前补0
	 * 1、srcString为null或"",则返回srcString。
	 * 2、start<0，则返回srcString。
	 * 3、end<0，则返回srcString。
	 * 4、start - end<0，返回srcString
	 * 返回的字符串的长度为start。
	 * 如果suffixString为null则返回srcString最前面fixLength个字符串。
	 * @param start 起始字符串长度
	 * @param end 终止字符串长度
	 * @param srcString 源字符串
	 * @return
	 */
	public static String addZeroPrefix(String srcString, int start, int end) {
		StringBuffer stringBuffer = new StringBuffer();
		//验证参数的合法性
		if ( (srcString == null) || (srcString == "")) {
			return srcString;
		}
		if ( (start < 0) || (end < 0) || (start - end) <= 0) {
			return srcString;
		}

		for (int i = 0; i < (start - end); i++) {
			stringBuffer.append("0");
		}
		return stringBuffer.toString() + srcString;
	}

	/**
	 * 取得正数number对应的定长的字符串，如果number位数不足fixLength则在前面补0。
	 * 比如 fixLength = 3：
	 * number = 123 ，则返回"123"
	 * number = 12  ，则返回"012"
	 * number = 1   ，则返回"001"
	 * number = 8762，则返回"762"
	 * number = 0   ，则返回"000"
	 * 以下几种情况返回null
	 * 1、number    < 0    或者
	 * 2、fixLength < 1
	 *
	 * @param number
	 * @param fixLengh
	 * @return
	 */
	public static String numberToFixLengthString(long number, int fixLength) {
		String fixLengthString = null;
		//符合要求，则进行处理
		if (number >= 0 && fixLength >= 1) {
			//1、得到fixLength个0对应的字符串
			String allZeroString = getRepeatString(fixLength, "0");
			//2、取得拼接的字符串，比如：number=4567,fixLength=3,则得到"0004567"
			String tempString = allZeroString + number;
			int intTempStringLength = tempString.length(); //一定大于fixLength
			//3、截取拼接的字符串的最后fixLength个字符
			fixLengthString = tempString.substring(intTempStringLength -
				fixLength);
		}
		//返回结果
		return fixLengthString;
	}

	/**
	 * 取得定长的字符串，如果字符串位数不足fixLength则在前面补0。
	 * 比如 fixLength = 3：
	 * number = 013 ，则返回"13"
	 * number = 12  ，则返回"12"
	 * number = 8762，则返回"762"
	 * number = 0   ，则返回"0"
	 *
	 * @param number
	 * @param fixLengh
	 * @return
	 */
	public static String stringToFixLengthString(String srcString,
												 int fixLength) {

		if ( (srcString == null) || (srcString.equals("")) || (fixLength < 0)) {
			return srcString;
		}
		if (0 <= (srcString.length() - fixLength) ||
			(srcString.length() - fixLength) <= srcString.length()) {
			srcString = srcString.substring(srcString.length() - fixLength);

		}
		try { //尝试将srcString转换成Long类型
			srcString = "" + Long.parseLong(srcString);
		}
		catch (Exception ignored) {
			return srcString;
		}
		//返回结果
		return srcString;
	}

	/**
	 * 得到repeatTime个metaString连接起来的字符串。
	 * 比如 repeatTime＝3：
	 * metaString为"a1"，则返回"a1a1a1"。
	 * metaString为"0"，则返回"000"。
	 *
	 * 以下情况返回null：
	 * 1、repeatTime <= 0     或者
	 * 2、metaString == null
	 *
	 * @param repeatTime 重复次数
	 * @param metaString 将被重复的字符串
	 * @return 字符串或者null
	 */
	public static String getRepeatString(int repeatTime, String metaString) {
		String repeatString = null;
		//符合条件，则进行处理
		if (repeatTime > 0 && metaString != null) {
			int intMetatStringLength = metaString.length();
			if (intMetatStringLength == 0) {
				//metaString为空字符串，则返回空字符串
				repeatString = "";
			}
			else {
				//执行到此repeatTime> 0 && intMetatStringLength > 0
				StringBuffer tempStringBuffer = new StringBuffer(repeatTime *
					intMetatStringLength);
				for (int i = 0; i < repeatTime; i++) {
					tempStringBuffer.append(metaString);
				}
				repeatString = tempStringBuffer.toString();
			}
			//***** 取得了符合要求的字符串 *****//
		}
		//返回结果
		return repeatString;
	}

	/**
	 * 得到devidedString被分割后的字符串。
	 * @param metaString 源字符串
	 * @param delim 分隔符
	 * @return 字符串或者null
	 */
	public static String getDividedString(String metaString, String delim) {
		String devidedString = null;
		//符合条件，则进行处理
		int index = -1;
		if (metaString != null && delim != null &&
			metaString.lastIndexOf(delim) != -1) {
			index = metaString.lastIndexOf(delim);
			devidedString = metaString.substring(0, index);
		}
		else {
			devidedString = metaString;
		}
		return devidedString;
	}

	/**
	 * 得到sourceString被分割后的字符串。
	 * 例如，sourceString="中华人民共和国(中国)于公元2003年发表告全世界(主要是告美国)人民书(2003年8月28日)"
	 *       delim="("
	 *       方法返回"中华人民共和国(中国)于公元2003年发表告全世界(主要是告美国)人民书"
	 * @param sourceString 源字符串
	 * @param delim 分隔符
	 * @return 字符串或者null
	 */
	public static String getLeftStringFromRight(String sourceString,
												String delim) {
		String target = "";
		int index = 0;

		index = sourceString.lastIndexOf(delim);
		if (index == 0) {
			target = sourceString;
		}
		else {
			target = sourceString.substring(0, index);
		}

		return target;
	}

	/**
	 * 得到metaString被截断的字符串。
	 * @param metaString 源字符串
	 * @param length 需要截断字符串的长度
	 * @return 字符串或者null
	 */
	public static String getTruncatedString(String metaString, int length) {
		if (metaString != null && length > 0) {
			if (metaString.length() > length) {
				metaString = metaString.substring(0, length);
				metaString = metaString + "......";
			}
		}
		return metaString;
	}

     /**
     * 去除掉字符串中第一次以给定字符串开头和结尾的部分
     * @param aimStr String      目标字符串
     * @param beginStr String    起始字符串
     * @param endStr String      结束字符串
     * @return String
     */
    public static String trimStr(String aimStr,String beginStr,String endStr){
       String newStr = aimStr;
       int iStart = aimStr.indexOf(beginStr);
       int iEnd = aimStr.indexOf(endStr)+endStr.length();
       if (iStart!=-1 && iEnd!= -1) {
           newStr = aimStr.substring(0,iStart) + aimStr.substring(iEnd,aimStr.length());
       }
       return newStr;
   }
    
    public static  String getLineStr(String metaString, int length) {
    	String returnStr = "";
		if (metaString != null && length > 0) {		
			String temStr = metaString ;
			int leg = temStr.length() ;			
			while(leg > length){			
				returnStr += temStr.substring(0, length) + "\n";
				temStr = temStr.substring(length,leg);			
				leg = temStr.length() ;				
			}
			returnStr += temStr;			
		}
		return returnStr;
	}
    
    /**
     * 得到metaString被截断的字符串。
     * @param metaString  目标字符串
     * @param len         需要截取的长度，一个汉字的长度为2
     * @return
     */
    public static String getTruncatedStringGBK(String metaString, int len) {
    	if (metaString ==null || metaString.equals("") || len<=0) {
			return "";
		}
		StringBuffer sb = new StringBuffer(len);
		int count = 0;
		for (int i = 0; i < metaString.length(); i++) {
			char c = metaString.charAt(i);
			if (c <= '\u00ff') {
				count++;
			} else {
				count += 2;
				if (count > len) {
					return sb.toString().trim();
				}
			}
			sb.append(c);
			if (count >= len) {
				return sb.toString().trim();
			}
		}
		return metaString;
	}
    
    /**
     * 得到url串中的参数名、参数值构成的MAP
     * 如 p1=v1&p2=v2&p3=v3，则返回参数名和值对应的HashMap
     * @param parmasString，如 p1=v1&p2=v2&p3=v3
     * @return HashMap 
     */
    public static HashMap getHtmlParamsMap (String parmasString){
    	if (parmasString==null || "".equals(parmasString)) {
			return null;
		}
    	HashMap<String, String> map = new HashMap<String, String>();	
    	String[] retS = parmasString.split("&");
		for(String s:retS){
			String[] p = s.split("=");
			if(p!=null&&p.length>0){
				map.put(p[0], p[1]);
			}
		}  	
    	return map;
    }
    
    /**
     * Map输出为字符串
     * @param map
     * @return
     */
    public static String mapToString(HashMap map){
    	if (map == null) {
			return "";
		}
    	StringBuffer temp = new StringBuffer();   	
    	for (Iterator itor = map.keySet().iterator(); itor.hasNext();) {
    		String key = (String)itor.next();
			temp.append(key).append("=").append(map.get(key)).append("\n");			
		}
    	
    	return temp.toString();
    }
    
    /**
     * 去掉字符串中的空格、回车、换行符、制表符
     * @param str
     * @return
     */
    public static String  replaceBlank(String str)   
    {   
       Pattern p = Pattern.compile("\\s*|\t|\r|\n");       
       //System.out.println("before:"+str);   
       Matcher m = p.matcher(str);   
       String after = m.replaceAll("");    
       //System.out.println("after:"+after);   
       return after;
    }   
    
    /**
     * 检查字符串是否为空
     * @param checkString
     * @return
     */
    public static boolean isEmpty(String checkString){	
		return (null==checkString || "".equals(checkString.trim()));	
	}

}
